package cool.doudou.doudada.iot.codec.core.api;

import cool.doudou.doudada.iot.codec.core.adapter.ICodecAdapter;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.osgi.framework.*;
import org.springframework.util.StringUtils;

import java.io.File;

/**
 * BundleApi
 *
 * @author jiangcs
 * @since 2022/09/29
 */
@Slf4j
@AllArgsConstructor
public class BundleApi {
    private BundleContext bundleContext;

    /**
     * 获取 Bundle 对象
     *
     * @param id BundleId
     * @return Bundle对象
     * @throws BundleException Bundle异常
     */
    public Bundle getById(Long id) throws BundleException {
        Bundle bundle = bundleContext.getBundle(id);
        if (bundle == null) {
            throw new BundleException("bundle not found");
        }
        return bundle;
    }

    /**
     * 安装 Bundle
     *
     * @param bundlePath Bundle路径
     * @param parentPath 父路径
     * @param fileName   Bundle文件名
     * @return BundleId
     * @throws BundleException Bundle异常
     */
    public Long install(String bundlePath, String parentPath, String fileName) throws BundleException {
        // bundle文件 父路径
        File bundleParentFile = new File(bundlePath, parentPath);
        if (!bundleParentFile.exists()) {
            bundleParentFile.mkdirs();
        }

        File bundleFile = new File(bundleParentFile, fileName);
        if (!bundleFile.exists()) {
            throw new BundleException("bundleFile not exists");
        }
        Bundle bundle = bundleContext.installBundle("file:" + bundleFile.getAbsolutePath());
        return bundle.getBundleId();
    }

    /**
     * 卸载 Bundle
     *
     * @param id BundleId
     * @throws BundleException Bundle异常
     */
    public void uninstall(Long id) throws BundleException {
        Bundle bundle = getById(id);
        bundle.uninstall();
    }

    /**
     * 开启 Bundle
     *
     * @param id BundleId
     * @throws BundleException Bundle异常
     */
    public void start(Long id) throws BundleException {
        Bundle bundle = getById(id);
        bundle.start();
    }

    /**
     * 停止 Bundle
     *
     * @param id BundleId
     * @throws BundleException Bundle异常
     */
    public void stop(Long id) throws BundleException {
        Bundle bundle = getById(id);
        bundle.stop();
    }

    /**
     * 获取 可用服务
     *
     * @param manufactureId 厂商ID
     * @param productId     产品ID
     * @return 编解码适配器
     */
    public ServiceReference<?>[] getAssignableService(String manufactureId, String productId) {
        String filter = null;
        if (StringUtils.hasLength(manufactureId) && StringUtils.hasLength(productId)) {
            filter = String.format("(&(manufactureId=%s)(productId=%s))", manufactureId, productId);
        } else if (StringUtils.hasLength(manufactureId)) {
            filter = String.format("(manufactureId=%s)", manufactureId);
        } else if (StringUtils.hasLength(productId)) {
            filter = String.format("(productId=%s)", productId);
        }

        ServiceReference<?>[] serviceReferences = null;
        try {
            serviceReferences = bundleContext.getServiceReferences(ICodecAdapter.class.getName(), filter);
        } catch (InvalidSyntaxException e) {
            log.error("get serviceReferences exception: ", e);
        }
        return serviceReferences;
    }

    /**
     * 获取 编码适配器
     *
     * @param serviceReference 服务引用
     * @return 编解码适配器
     */
    public ICodecAdapter getCodecAdapter(ServiceReference<?> serviceReference) {
        return (ICodecAdapter) bundleContext.getService(serviceReference);
    }
}
